using System;
using System.Collections.Generic;

namespace NCommet.Core.Agents
{
    /// <summary>
    /// <c>ITypedTreeValidator</c> performs validation of several operations using primarly item types to determine if
    /// an operation is allowed.
    /// </summary>
    public interface ITypedTreeValidator
    {
        #region Can ... Actions
        /// <summary>
        /// Checks if the item can be set as root.
        /// </summary>
        /// <param name="CandidateRoot">The item that is checked.</param>
        /// <returns>True, if the item can be set as root.</returns>
        bool CanSetRoot(Item CandidateRoot);

        /// <summary>
        /// Checks if the item can be set as root.
        /// If the operation is not allowed, validation errors will be returned in <paramref name="ValidationSummary"/>
        /// </summary>
        /// <param name="CandidateRoot">The item that is checked.</param>
        /// <param name="ValidationSummary">The validation errors returned.</param>
        /// <returns>True, if the item can be set as root.</returns>
        bool CanSetRoot(Item CandidateRoot, out ICollection<string> ValidationSummary);

        /// <summary>
        /// Checks if <paramref name="CandidateChild"/> can be attached as a child of <paramref name="Parent"/>
        /// </summary>
        /// <param name="Parent">The parent item.</param>
        /// <param name="CandidateChild">The candidate child item.</param>
        /// <returns>True, if <paramref name="CandidateChild"/> can be attached as a child of <paramref name="Parent"/></returns>
        bool CanAttach(Item Parent, Item CandidateChild);

        /// <summary>
        /// Checks if <paramref name="CandidateChild"/> can be attached as a child of <paramref name="Parent"/>
        /// If the operation is not allowed, validation errors will be returned in <paramref name="ValidationSummary"/>
        /// </summary>
        /// <param name="Parent">The parent item.</param>
        /// <param name="CandidateChild">The candidate child item.</param>
        /// <param name="ValidationSummary">The validation errors returned.</param>
        /// <returns>True, if <paramref name="CandidateChild"/> can be attached as a child of <paramref name="Parent"/></returns>
        bool CanAttach(Item Parent, Item CandidateChild, out ICollection<string> ValidationSummary);
        
        /// <summary>
        /// Checks if <paramref name="Child"/> can be removed from its parent.
        /// </summary>
        /// <param name="Parent">The parent item.</param>
        /// <param name="Child">The child item.</param>
        /// <returns>True, if <paramref name="Child"/> can be removed from its parent.</returns>
        bool CanRemove(Item Parent, Item Child);

        /// <summary>
        /// Checks if <paramref name="Child"/> can be removed from its parent.
        /// If the operation is not allowed, validation errors will be returned in <paramref name="ValidationSummary"/>
        /// </summary>
        /// <param name="Parent">The parent item.</param>
        /// <param name="Child">The child item.</param>
        /// <param name="ValidationSummary">The validation errors returned.</param>
        /// <returns>True, if <paramref name="Child"/> can be removed from its parent.</returns>
        bool CanRemove(Item Parent, Item Child, out ICollection<string> ValidationSummary);

        /// <summary>
        /// Checks if <paramref name="Container"/> can contain <paramref name="CandidateContent"/> as its content.
        /// </summary>
        /// <param name="Container">The container item.</param>
        /// <param name="CandidateContent">The candidate content.</param>
        /// <returns>True, if <paramref name="Container"/> can contain <paramref name="CandidateContent"/> as its content.</returns>
        bool CanContain(Item Container, ContentBase CandidateContent);

        /// <summary>
        /// Checks if <paramref name="Container"/> can contain <paramref name="CandidateContent"/> as its content.
        /// If the operation is not allowed, validation errors will be returned in <paramref name="ValidationSummary"/>
        /// </summary>
        /// <param name="Container">The container item.</param>
        /// <param name="CandidateContent">The candidate content.</param>
        /// <param name="ValidationSummary">The validation errors returned.</param>
        /// <returns>True, if <paramref name="Container"/> can contain <paramref name="CandidateContent"/> as its content.</returns>
        bool CanContain(Item Container, ContentBase CandidateContent, out ICollection<string> ValidationSummary);

        #endregion

        #region Get Actions

        /// <summary>
        /// Gets the valid child item types for the given item.
        /// </summary>
        /// <param name="Parent">The given parent item.</param>
        /// <returns>A collection of the valid child item types for <paramref name="Parent"/></returns>
        ICollection<string> GetValidChildItemTypes(Item Parent);

        /// <summary>
        /// Gets the valid item types for a root item.
        /// </summary>
        /// <returns>A collection of the valid item types for a root item.</returns>
        ICollection<string> GetValidRootItemTypes();

        /// <summary>
        /// Gets the valid content types for the given item.
        /// Content types are returned as fully qualified type names.
        /// </summary>
        /// <param name="Container">The given item.</param>
        /// <returns>A collection of the valid content types for <paramref name="Container"/></returns>
        ICollection<string> GetValidContentTypes(Item Container);

        #endregion
    }
}
